Repository navigation
fix(recompiler): emit a GPU-selected formatted buffer access through one shared function - #2349
Conversation
|
Tested on Linux (CachyOS x86_64, Intel RPL-S iGPU / Mesa 26.3.0-devel / Vulkan 1.4.363, GCC 16.2.1) at
LGTM! |
…one shared function A formatted buffer load or store through a GPU-selected descriptor still emitted the switch over every buffer format inline, at each access. A Ghost of Yotei compute pass with ~300 such accesses compiled to 37M SPIR-V words, and its pipeline took 40 s or more to create. The switch is now emitted once per component count, direction, d16, coherence, kind and stop mode, as a SPIR-V function that takes the descriptor fields, the offsets and the access's PC. When faults stop the invocation, the helper returns whether one did and the caller stops there. BDA faults record the PC from BdaInstructionPc, the access's own PC or the one a shared helper takes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Rebased onto current Checked on Linux (RADV) on the rebased tree: libSceAgc + libSceAgcDriver ctest green (334/335, the one failure is a stale registration not present on |
0690a90 to
8dbea2c
Compare
What
#1959 moves the switch over every buffer format into one function per resource when the descriptor is prepared. It keeps the inline switch for GPU-selected descriptors (
memory.gpuDescriptor). For those, everybuffer_load_format_*/buffer_store_format_*still emits all 77 cases inline, and each case inlines the address computation, bounds checks and BDA reads offormatted().A title with about 300 such accesses in one compute program (Ghost of Yōtei, PPSA26344, 0x8000289300, 102 guest blocks) compiles to 37.1M SPIR-V words: 292
OpSwitches, about 700k blocks, 287 distinct block shapes. Each pipeline takes 40 s or more to create on NVIDIA, and each shader disk-cache entry is up to ~300 MB. This is probably also the 13.4M-word module reported on #1183.formattedGpuCallemits oneDontInlineSPIR-V function per component count, direction, d16, coherence, kind and stop mode, and runsformatSwitchinside it.{value, stopped}(juststoppedfor a store). Inside it, a stop returns that throughbdaStopValue, asread_bda_spandoes. The caller callsStopBdaInvocationIfon the flag, so the pixel-shader interlock andOpKillhandling stay in the entry function.BdaInstructionPcreturns the instruction's PC, or the PC parameter inside the shared function (SpirvEmitterState::bdaPcOverride). The BDA read, write, store, atomic and overflow paths use it, so a fault records the PC of the access that faulted.Tested
Windows 11, MinGW-w64 GCC 15.2.0, RTX 4090 (driver 617.42).
agc_formatted_buffer_oncegains a GPU-selected case: dword 3 of the V# comes fromv_readfirstlane_b32 s11, v0.Checklist
main; no other open PR implements the same functions (stacked on fix(recompiler): emit a formatted buffer access through one function per resource #1959)NotImplemented_nid_no_patch); silent stubs are listed in TechnicalDebt.mdfiles or images added to the repository (attach them to this PR)🤖 Generated with Claude Code